package testCases;

import static org.junit.Assert.*;
import org.junit.*;

import cs470.kalman.Matrix;


public class TestMatrix 
{
	static Matrix a3x2;
	static Matrix b3x2;
	static Matrix c2x3;
	static Matrix aTrans;
	static Matrix cTrans;
	static Matrix d2x2;
	static Matrix e3x3;
	static Matrix f4x4;
	
	@BeforeClass 
	public static void setUp() throws Exception
	{
		a3x2 = new Matrix (new double[][]{{1, 2},{3, 4}, {5, 6}});
		b3x2 = new Matrix (new double [][] {{2, 3}, {4, 5},{6, 7}});
		c2x3 = new Matrix (new double [][] {{1, 1, 1}, {2, 2, 2}});
		aTrans = new Matrix(new double [][] {{1, 3, 5}, {2, 4, 6}});
		cTrans = new Matrix (new double [][] {{1, 2}, {1, 2}, {1, 2}});
		d2x2 = new Matrix(new double [][] {{1, 2}, {3, 4}});
		e3x3 = new Matrix(new double [][] {{1, -1, 1}, {2, 3, 1}, {3, 2, 1}});
		f4x4 = new Matrix (new double [][]{{1, 2, 3, 4}, {4, 3, 2, 1}, {6, 4, 3, 2}, {1, 2, 4, 5}});
	}
	
	@Test
	public void testAdding() throws Exception 
	{
		Matrix sum = a3x2.add(b3x2);
		Matrix answer = new Matrix (new double [][]{{3, 5}, {7, 9}, {11, 13}});
		assertTrue(answer.equals(sum));
	}

	@Test(expected = Exception.class)
	public void testAddingException() throws Exception
	{
		Matrix sum = a3x2.add(c2x3);
	}
	
	@Test
	public void testInvert()throws Exception
	{
		Matrix identity = new Matrix(new double[][]{{1, 0}, {0, 1}});
		assertTrue("invert 2x2", identity.equals(d2x2.multiply(d2x2.invert())));
		identity = new Matrix(new double[][] {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}});
		assertTrue("invert 3x3", identity.equals(e3x3.multiply(e3x3.invert())));
		identity = new Matrix(new double[][] {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}});
		assertTrue("invert 4x4", identity.equals(f4x4.multiply(f4x4.invert())));
		assertFalse("FAIL invert", identity.equals(f4x4.multiply(f4x4)));
	}
	
	@Test
	public void testTranspose() throws Exception
	{
		Matrix temp = a3x2.transpose();
		assertTrue(temp.equals(aTrans));
		assertFalse(temp.equals(cTrans));
		
		temp = c2x3.transpose();
		assertFalse(temp.equals(aTrans));
		assertTrue(temp.equals(cTrans));
	}
	
	@Test
	public void testMultiplication() throws Exception
	{
		Matrix temp = a3x2.multiply(c2x3);
		Matrix product = new Matrix(new double [][] {{5, 5, 5}, {11, 11, 11}, {17, 17, 17}});
		assertTrue(temp.equals(product));
		
		temp = c2x3.multiply(cTrans);
		product = new Matrix (new double [][] {{3, 6}, {6, 12}});
		assertTrue(temp.equals(product));
	}
	
	@Test(expected = Exception.class)
	public void testMultiplicationException() throws Exception
	{
		Matrix temp = a3x2.multiply(b3x2);
	}
}
